#include<iostream>
// int abc(int a, int b, int c)
// {
//     return a + b + c;
// }
// float abc(float a, float b, float c)
// {
//     return a + b + c;
// }

/**
 * 模板函数: 值传递
 */
template<class T> // template<typename T>
T abcV(T a, T b, T c)
{
    return a + b + c;
}

/**
 * 引用传递
 */
template <typename T>
T abcR(T& a, T& b, T& c)
{
    return a + b + c;
}

/**
 * 常量传递
 */
template <class T>
T abcC(const T& a, const T& b, const T& c)
{
    return a + b + c;
}

/**
 * 通用版本
 */
template <class Ta, class Tb, class Tc>
Ta abc(Ta a, Tb b, Tc c)
{
    return a + b + c;
}

/**
 * 模板函数: 指针传递
 */
template <class T>
T abcP(T* a, T* b, T* c)
{
    return *a + *b + *c;
}

/**
* 引用返回
*/
template <class T>
T& mysteryR(int a, T& z)
{
    return z;
}

/**
* 常量引用返回
*/
template <class T>
const T& mysteryC(int a, T& z)
{
    return z;
}

/**
 * 获取静态数组大小
 * int a[] = {1, 2, 3};
 * int *ap = a; // a pointer, size is lost
 * int (&ar)[3] = a; // a reference to the array, size is not lost
 * std::size_t N：这是一个非类型模板参数（也称为“非类型参数”），用于表示数组的大小。
 * std::size_t 是一个标准类型，通常用于表示大小和索引，它的实际类型是无符号整数类型，可以确保它足够大以容纳任何可能的数组索引或大小。
 */
template <class T, std::size_t N>
std::size_t array_size(const T(&)[N])
{
    return N;
}

int main()
{
    int ia = 1, ib = 2, ic = 3;
    long la = 1, lb = 2, lc = 3;
    double da = 1.1, db = 2.2, dc = 3.3;
    int arr[5];
    std::cout
        << abcV(ia, ib, ic) << '\n'
        << abcR(la, lb, lc) << '\n'
        << abcC(da, db, dc) << '\n'
        << abc(ia, lb, dc) << '\n'
        << mysteryR(ia, dc) << '\n'
        << array_size(arr) << '\n'
        << std::endl;
    return 0;
}
